<?php
// +‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
// | NewThink [ Think More,Think Better! ]
// +‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
// | Copyright (c) 2016~2018 http://www.newthink.cc All rights reserved.
// +‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
// | 版权所有：山西创泰网络科技有限公司
// +‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
// | Author: lk Date:2019/7/25 Time:15:13
// +‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐

namespace app\common\service;

use app\common\service\companyIndustry\industrymodel\TsinghuaDrainEmissionToFacilityParam;
use think\Db;

class WorkingModelService
{
    private $modelUrl = 'http://39.96.33.44:8081/renren-api/jnrdgk/';

    /**
     * 预测模型
     * @param $companyId
     * @param $facilityId
     * @param $startTime
     * @param $endTime
     * @param string $planNumber
     * @param string $tsinghuaPlanName
     * @return mixed
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function forecast($companyId, $facilityId, $startTime, $endTime, $planNumber = "", $tsinghuaPlanName = "")
    {
        $cis = new CompanyIndustryService($startTime, $endTime, $facilityId);

        #获取治理设施相关信息
        $facilityInfo = $this->facilityConversion($facilityId);

        if ($facilityInfo['type'] == "TS") {
            #入口烟气量
            $gasInVol = $cis->getGasInVol(60);
            #出口烟气量
            $gasOutVol = $cis->getGasOutVol(60);
            #入口硫浓度
            $so2InDen = $cis->getSO2InDen();
            #出口目标硫浓度, 模型使用方案值运行浓度
            $tsinghua  = new TsinghuaDrainEmissionToFacilityParam();
            $so2OutDen = $tsinghua->getPlanParamByFacilityId($facilityId, $planNumber, $tsinghuaPlanName, 'SO2')['concentration'];
            #入口O2%
            $o2InPer = $cis->getO2InPer();
            $o2InPer < 0 && $o2InPer = 0;
            #出口O2%
            $o2OutPer = $cis->getO2OutPer();
            #入口烟温
            $gasInTemp = $cis->getGasInTemp();
            #出口烟温
            $gasOutTemp = $cis->getGasOutTemp();
            #石灰石粉品质
            $caQual = $cis->getCaQual();
            #石灰石浆液密度
            $caDen = $cis->getCaDen();
            #PH值
            $Ph = $cis->getPh();

            #调用模型
            if ($facilityInfo['machine_id'] == 1) {
                $result = $this->tsForecast1($gasInVol, $gasOutVol, $so2InDen, $so2OutDen, $o2InPer, $o2OutPer, $gasInTemp, $gasOutTemp, $caQual, $caDen, $Ph);
            } else if ($facilityInfo['machine_id'] == 2) {
                $result = $this->tsForecast2($gasInVol, $gasOutVol, $so2InDen, $so2OutDen, $o2InPer, $o2OutPer, $gasInTemp, $gasOutTemp, $caQual, $caDen, $Ph);
            } else {
                throw new \Exception('未知机组');
            }
        } else if ($facilityInfo['type'] == "TX") {
            #入口烟气量
            $gasInVol = $cis->getGasInVol(60);
            #入口NOx浓度
            $noxInDen = $cis->getNOxInDen();
            #出口NOx浓度
            $noxOutDen = $cis->getNOxOutDen();
            #获取入口O2%
            $o2InPer = $cis->getO2InPer();
            $o2InPer < 0 && $o2InPer = 0;
            #获取出口O2%
            $o2OutPer = $cis->getO2OutPer();
            #入口烟温
            $gasInTemp = $cis->getGasInTemp();
            #出口烟温
            $gasOutTemp = $cis->getGasOutTemp();
            #氨逃逸浓度
            $nh3OutDen = $cis->getNH3OutDen();

            #调用模型
            $result = $this->txForecast($gasInVol, $noxInDen, $noxOutDen, $o2InPer, $o2OutPer, $gasInTemp, $gasOutTemp, $nh3OutDen);
        } else {
            throw new \Exception('未知类型');
        }
        $result = json_decode($result, true);
        unset($result['msg'], $result['code']);

        return $result;
    }

    /**
     * 正向模型
     * @param $companyId
     * @param $facilityId
     * @param $startTime
     * @param $endTime
     * @param string $planNumber
     * @param string $tsinghuaPlanName
     * @return mixed
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function reaction($companyId, $facilityId, $startTime, $endTime, $planNumber = "", $tsinghuaPlanName = "")
    {
        $cis = new CompanyIndustryService($startTime, $endTime, $facilityId);

        #获取治理设施相关信息
        $facilityInfo = $this->facilityConversion($facilityId);

        if ($facilityInfo['type'] == "TS") {
            #获取预测模型的供浆量及循环泵组合
            $forecastData = $this->forecast($companyId, $facilityId, $startTime, $endTime, $planNumber, $tsinghuaPlanName);

            #入口烟气量
            $gasInVol = $cis->getGasInVol(60);
            #入口硫浓度
            $so2InDen = $cis->getSO2InDen();
            #入口O2%
            $o2InPer = $cis->getO2InPer();
            $o2InPer < 0 && $o2InPer = 0;
            #入口烟温
            $gasInTemp = $cis->getGasInTemp();
            #供浆量
            $slurrySupply = $forecastData['slurrySupply'] ?? null;
            #石灰石粉品质
            $caQual = $cis->getCaQual();
            #石灰石浆液密度
            $caDen = $cis->getCaDen();
            #循环泵组合
            $pumpGroup = $forecastData['pumpGroup'] ?? null;

            #调用模型
            if ($facilityInfo['machine_id'] == 1) {
                $result = $this->tsReaction1($gasInVol, $so2InDen, $o2InPer, $gasInTemp, $slurrySupply, $caQual, $caDen, $pumpGroup);
            } elseif ($facilityInfo['machine_id'] == 2) {
                $result = $this->tsReaction2($gasInVol, $so2InDen, $o2InPer, $gasInTemp, $slurrySupply, $caQual, $caDen, $pumpGroup);
            } else {
                throw new \Exception('未知机组');
            }
        } else if ($facilityInfo['type'] == "TX") {
            #入口烟气量
            $gasInVol = $cis->getGasInVol(60);
            #入口NOx浓度
            $noxInDen = $cis->getNOxInDen();
            #获取入口O2%
            $o2InPer = $cis->getO2InPer();
            $o2InPer < 0 && $o2InPer = 0;
            #入口烟温
            $gasInTemp = $cis->getGasInTemp();
            #进氨气量
            $ng3InVol = $cis->getNH3InVol(60);

            #调用模型
            $result = $this->txReaction($gasInVol, $noxInDen, $o2InPer, $gasInTemp, $ng3InVol);
        } else {
            throw new \Exception('未知类型');
        }
        $result = json_decode($result, true);
        unset($result['msg'], $result['code']);
        return $result;
    }

    /**
     * 通过设施ID获取信息
     * @param $facilityId
     * @return array
     * @throws \Exception
     */
    private function facilityConversion($facilityId): array
    {
        $sql      = "SELECT `name` FROM `basic_facility` WHERE id = ?";
        $facility = Db::query($sql, array($facilityId));
        if (empty($facility)) {
            throw new \Exception('未知设施');
        }
        $facilityName = $facility[0]['name'];

        $arr            = explode('-', $facilityName);
        $str            = substr($arr[1], strlen($arr[1]) - 1, 1);
        $facilityNumber = is_numeric($str) ? chr($str + 96) : false;

        $typeAlias  = '';
        $typeNumber = '';
        if ($arr[0] == "TX") {
            $typeAlias  = 'NO2';
            $typeNumber = 1;
        } else if ($arr[0] == "TS") {
            $typeAlias  = 'SO2';
            $typeNumber = 2;
        }

        $result = [
            'machine_id' => (int)substr($arr[1], 0, 1),//机组
            'facility' => $facilityNumber,//治理设施,用于工况原始数据
            'type' => $arr[0],//类型 TX,TS
            'typeAlias' => $typeAlias,//类型别名NO2,SO2
            'typeNumber' => $typeNumber,//MYSQL 类型type
        ];

        return $result;
    }

    /**
     * 脱硫预测模型机组1
     * @param string $gasInVol 入口烟气量
     * @param string $gasOutVol 出口烟气量
     * @param string $so2InDen 入口硫浓度
     * @param string $so2OutDen 出口目标硫浓度
     * @param string $o2InPer 入口O2%
     * @param string $o2OutPer 出口O2%
     * @param string $gasInTemp 入口烟温
     * @param string $gasOutTemp 出口烟温
     * @param string $caQual 石灰石粉品质
     * @param string $caDen 石灰石浆液密度
     * @return mixed
     */
    private function tsForecast1($gasInVol, $gasOutVol, $so2InDen,
                                 $so2OutDen, $o2InPer, $o2OutPer,
                                 $gasInTemp, $gasOutTemp, $caQual, $caDen, $Ph)
    {
        $fmt = '%stuoliu_forecast_1?gasInVol=%s&gasOutVol=%s&SO2InDen=%s&SO2OutDen=%s&O2InPer=%s&O2OutPer=%s&gasInTemp=%s&gasOutTemp=%s&CaQual=%s&CaDen=%s&Ph=%s';

        $url = sprintf($fmt, $this->modelUrl, $gasInVol,
            $gasOutVol, $so2InDen, $so2OutDen, $o2InPer,
            $o2OutPer, $gasInTemp, $gasOutTemp, $caQual, $caDen, $Ph);

        $result = get($url);

        return $result;
    }

    /**
     * 脱硫预测模型机组2
     * @param string $gasInVol 入口烟气量
     * @param string $gasOutVol 出口烟气量
     * @param string $so2InDen 入口硫浓度
     * @param string $so2OutDen 出口目标硫浓度
     * @param string $o2InPer 入口O2%
     * @param string $o2OutPer 出口O2%
     * @param string $gasInTemp 入口烟温
     * @param string $gasOutTemp 出口烟温
     * @param string $caQual 石灰石粉品质
     * @param string $caDen 石灰石浆液密度
     * @return mixed
     */
    private function tsForecast2($gasInVol, $gasOutVol, $so2InDen,
                                 $so2OutDen, $o2InPer, $o2OutPer,
                                 $gasInTemp, $gasOutTemp, $caQual, $caDen, $Ph)
    {
        $fmt = '%stuoliu_forecast_2?gasInVol=%s&gasOutVol=%s&SO2InDen=%s&SO2OutDen=%s&O2InPer=%s&O2OutPer=%s&gasInTemp=%s&gasOutTemp=%s&CaQual=%s&CaDen=%s&Ph=%s';

        $url = sprintf($fmt, $this->modelUrl, $gasInVol,
            $gasOutVol, $so2InDen, $so2OutDen, $o2InPer,
            $o2OutPer, $gasInTemp, $gasOutTemp, $caQual, $caDen, $Ph);

        $result = get($url);

        return $result;
    }

    /**
     * 脱硫正向模型机组1
     * @param string $gasInVol 入口烟气量
     * @param string $so2InDen 入口硫浓度
     * @param string $o2InPer 入口O2%
     * @param string $gasInTemp 入口烟温
     * @param string $slurrySupply 供浆量
     * @param string $caQual 石灰石粉品质
     * @param string $caDen 石灰石浆液密度
     * @param string $pumpGroup 循环泵运行组合
     * @return mixed
     */
    private function tsReaction1($gasInVol, $so2InDen, $o2InPer,
                                 $gasInTemp, $slurrySupply, $caQual,
                                 $caDen, $pumpGroup)
    {
        $fmt = '%stuoliu_reaction_1?gasInVol=%s&SO2InDen=%s&O2InPer=%s&gasInTemp=%s&slurrySupply=%s&CaQual=%s&CaDen=%s&pumpGroup=%s';

        $url = sprintf($fmt, $this->modelUrl, $gasInVol,
            $so2InDen, $o2InPer, $gasInTemp, $slurrySupply,
            $caQual, $caDen, $pumpGroup);

        $result = get($url);

        return $result;
    }

    /**
     * 脱硫正向模型机组2
     * @param string $gasInVol 入口烟气量
     * @param string $so2InDen 入口硫浓度
     * @param string $o2InPer 入口O2%
     * @param string $gasInTemp 入口烟温
     * @param string $slurrySupply 供浆量
     * @param string $caQual 石灰石粉品质
     * @param string $caDen 石灰石浆液密度
     * @param string $pumpGroup 循环泵运行组合
     * @return mixed
     */
    private function tsReaction2($gasInVol, $so2InDen, $o2InPer,
                                 $gasInTemp, $slurrySupply, $caQual,
                                 $caDen, $pumpGroup)
    {
        $fmt = '%stuoliu_reaction_2?gasInVol=%s&SO2InDen=%s&O2InPer=%s&gasInTemp=%s&slurrySupply=%s&CaQual=%s&CaDen=%s&pumpGroup=%s';

        $url = sprintf($fmt, $this->modelUrl, $gasInVol,
            $so2InDen, $o2InPer, $gasInTemp, $slurrySupply,
            $caQual, $caDen, $pumpGroup);

        $result = get($url);

        return $result;
    }

    /**
     * 脱硝预测模型（不分机组）
     * @param string $gasInVol 入口烟气量
     * @param string $noxInDen 入口NOx浓度
     * @param string $noxOutDen 出口NOx浓度
     * @param string $o2InPer 入口O2%
     * @param string $o2OutPer 出口O2%
     * @param string $gasInTemp 入口烟温
     * @param string $gasOutTemp 出口烟温
     * @param string $nh3OutDen 氨逃逸浓度
     * @return mixed
     */
    private function txForecast($gasInVol, $noxInDen, $noxOutDen,
                                $o2InPer, $o2OutPer, $gasInTemp,
                                $gasOutTemp, $nh3OutDen)
    {

        $fmt = '%stuoxiao_forecast?gasInVol=%s&NOxInDen=%s&NOxOutDen=%s&O2InPer=%s&O2OutPer=%s&gasInTemp=%s&gasOutTemp=%s&NH3OutDen=%s';

        $url = sprintf($fmt, $this->modelUrl, $gasInVol,
            $noxInDen, $noxOutDen, $o2InPer, $o2OutPer,
            $gasInTemp, $gasOutTemp, $nh3OutDen);

        $result = get($url);

        return $result;
    }

    /**
     * 脱硝正向模型（不分机组）
     * @param string $gasInVol 入口烟气量
     * @param string $noxInDen 入口NOx浓度
     * @param string $o2InPer 入口O2%
     * @param string $gasInTemp 入口烟温
     * @param string $nh3InVol 进氨气量
     * @return mixed
     */
    private function txReaction($gasInVol, $noxInDen, $o2InPer,
                                $gasInTemp, $nh3InVol)
    {
        $fmt = '%stuoxiao_reaction?gasInVol=%s&NOxInDen=%s&O2InPer=%s&gasInTemp=%s&NH3InVol=%s';

        $url = sprintf($fmt, $this->modelUrl, $gasInVol, $noxInDen, $o2InPer, $gasInTemp, $nh3InVol);

        $result = get($url);

        return $result;
    }

}
